home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-09-01 | 10.9 KB | 307 lines | [TEXT/PJMM] |
- {****************************************************}
- {}
- { CThermometer.p }
- { A Thermometer Class with two subclasses }
- { Class which displays progress of an operation via a filling rectangle or circle }
- { SUPERCLASS = CObject }
- { Copyright © 1990, Captain Mac Enterprises. All rights reserved. }
- { You're free to modify this for your own needs. Please don't modify and redistribute }
- { 8/23/90 }
- {}
- {****************************************************}
-
- unit CThermometer;
- interface
- uses
- Script, MiniIntf; {in a real project, replace MiniIntf with TCL}
-
- type
- CThermometer = object(CObject)
- {internal instance variables}
- thermDialog: DialogPtr; {dialog thermometer is drawn in}
- savePort: GrafPtr; {used to save and restore port of caller}
- thermRect: Rect; {rect of userItem in dialog, this eliminates calling GetDItem repeatedly}
-
- {user defined instance variables}
- updateIncr: Integer; {caller sets how often to update thermometer by percent, 1 - 100}
- {numbers that divide into 100 evenly look best}
- thermPattern: Pattern; {pattern to fill thermometer with}
- wantsTicks: Boolean; {add tick marks to thermometer? not recommended for pies}
-
- {methods}
- procedure IThermometer (msg: Str255; updatePercent: Integer; fillPattern: Pattern; wantTicks: Boolean);
- {pass message to be displayed and increment to fill thermometer in}
- procedure ChangeMessage (newMsg: Str255);
- procedure Free;
- {get rid of dialog}
- override;
- end;
-
- CBarTherm = object(CThermometer)
- procedure IThermometer (msg: Str255; updatePercent: Integer; fillPattern: Pattern; wantTicks: Boolean);
- override;
- {pass message to be displayed and increment to fill thermometer in}
- function AdjThermometer (percentToFill: Integer): Boolean;
- {pass percent of thermometer to fill, 0 to 100}
- end;
-
- CPieTherm = object(CThermometer)
- procedure IThermometer (msg: Str255; updatePercent: Integer; fillPattern: Pattern; wantTicks: Boolean);
- override;
- {pass message to be displayed and increment to fill thermometer in}
- function AdjThermometer (percentToFill: Integer): Boolean;
- {pass percent of thermometer to fill, 0 to 100}
- end;
-
- implementation
-
-
- {****************************************************}
- {}
- { CenterWindow }
- { Center a window on the screen }
- {}
- {****************************************************}
- procedure CenterWindow (theWindow: WindowPtr);
- var
- h, v: Integer;
- begin {CenterWindow}
- with theWindow^, portRect do
- begin
- h := (screenBits.bounds.right - screenBits.bounds.left) div 2 - (right - left) div 2;
- v := GetMBarHeight div 2 + (screenBits.bounds.bottom - screenBits.bounds.top) div 2 - (bottom - top) div 2;
- end;
- MoveWindow(theWindow, h, v, True);
- end; {CenterWindow}
-
-
- {****************************************************}
- {}
- { ProcessCancelled }
- { Return if command-period was pressed }
- {}
- {****************************************************}
- function ProcessCancelled: Boolean;
- var
- theEvent: EventRecord;
- cmdDown: Boolean;
- ch: Char;
- begin {ProcessCancelled}
- if GetNextEvent(keyDownMask, theEvent) then {look at keyDown events only}
- with theEvent do
- begin
- cmdDown := BitAnd(modifiers, cmdKey) <> 0; {is the command key down}
- ch := Chr(BitAnd(message, charCodeMask)); {get char code of key pressed & convert to char}
- ProcessCancelled := cmdDown & (ch = '.'); {and the answer is}
- end
- else
- ProcessCancelled := False;
- end; {ProcessCancelled}
-
-
- {****************************************************}
- {}
- { CalcPoint }
- { Given an angle from 0 (degrees) and radius (pixels), returns point on a circle }
- {}
- {****************************************************}
- function CalcPoint (angle, radius: Integer): Point; {angle from 0 and radius}
- const
- pi = 3.1415926535897932;
- begin {CalcPoint}
- CalcPoint.h := Round(radius * Sin(angle / 360.0 * 2.0 * pi));
- CalcPoint.v := Round(radius * Cos(angle / 360.0 * 2.0 * pi));
- end; {CalcPoint}
-
-
- {****************************************************}
- {}
- { CThermometer.IThermometer }
- { Initialize a CThermometer object }
- {}
- {****************************************************}
- procedure CThermometer.IThermometer (msg: Str255; updatePercent: Integer; fillPattern: Pattern; wantTicks: Boolean);
- begin {CThermometer.IThermometer}
- thermDialog := nil;
- if (updatePercent > 0) & (updatePercent <= 100) then
- updateIncr := updatePercent {init updateIncr instance variable}
- else
- updateIncr := 5; {if updatePercent not 1 - 100 then default to 5}
- thermPattern := fillPattern;
- wantsTicks := wantTicks;
- end; {CThermometer.IThermometer}
-
-
- {****************************************************}
- {}
- { CThermometer.ChangeMessage }
- { Changes a CThermometer message }
- {}
- {****************************************************}
- procedure CThermometer.ChangeMessage (newMsg: Str255);
- var
- textRect: Rect;
- begin
- GetPort(savePort);
- SetPort(thermDialog);
- SetRect(textRect, 52, 14, 324, 65);
- FrameRect(textRect);
- TextBox(Pointer(Ord(@newMsg) + 1), Length(newMsg), textRect, teJustLeft);
- SetPort(savePort);
- end;
-
-
- {****************************************************}
- {}
- { CThermometer.Free }
- { Dispose of CThermometer stuff }
- {}
- {****************************************************}
- procedure CThermometer.Free;
- begin {CThermometer.Free}
- if thermDialog <> nil then {make sure dialog existed before disposing of it}
- DisposDialog(thermDialog); {trash the dialog no longer needed}
- inherited Free; {let CObject clean up memory used by object itself}
- end; {CThermometer.Free}
-
-
- {****************************************************}
- {}
- { CBarTherm.IThermometer }
- { Initialize a CBarTherm object }
- {}
- {****************************************************}
- procedure CBarTherm.IThermometer (msg: Str255; updatePercent: Integer; fillPattern: Pattern; wantTicks: Boolean);
- var
- dlogRect: Rect;
- lowStr, highStr: Str255;
- span, ticksCount, i, h: Longint;
- begin {CBarTherm.IThermometer}
- GetPort(savePort);
- inherited IThermometer(msg, updatePercent, fillPattern, wantTicks);
- SetRect(dlogRect, 10, 32, 394, 148);
- thermDialog := NewDialog(nil, dlogRect, '', False, 1, WindowPtr(-1), False, 0, nil);
- SetPort(thermDialog);
- CenterWindow(thermDialog);
- ShowWindow(thermDialog); {show the dialog}
- SetRect(dlogRect, 52, 14, 324, 65);
- TextBox(Pointer(Ord(@msg) + 1), Length(msg), dlogRect, teJustLeft);
- SetRect(thermRect, 52, 78, 324, 94);
- DrawDialog(thermDialog); {draw the dialog}
- FrameRect(thermRect); {frame the userItem}
-
- if wantsTicks then {caller wants tick marks displayed}
- begin
- span := thermRect.right - thermRect.left; {pixel span of thermometer}
- ticksCount := Trunc(100 / updateIncr) + 1; {how many tick marks are needed}
- h := 0; {offset between tick marks}
- for i := 1 to ticksCount do
- begin
- MoveTo(thermRect.left + h, thermRect.bottom); {make a tick mark}
- LineTo(thermRect.left + h, thermRect.bottom + 2);
- h := (i * updateIncr * span div 100) - 1; {calculate next offset}
- end; {for i}
- end; {if wantsTicks}
-
- InsetRect(thermRect, 1, 1); {inset rect 1 pixel so fill pattern does not erase frame}
- lowStr := '0%'; {thermometer labels}
- highStr := '100%';
- MoveTo(thermRect.left, thermRect.top - 4); {draw scale}
- DrawString(lowStr);
- MoveTo(thermRect.right - StringWidth(highStr), thermRect.top - 4);
- DrawString(highStr);
- SetPort(savePort);
- end; {CBarTherm.IThermometer}
-
-
- {****************************************************}
- {}
- { CBarTherm.AdjThermometer }
- { Adjust a CBarTherm object }
- { Returns True if Command-period was pressed }
- {}
- {****************************************************}
- function CBarTherm.AdjThermometer (percentToFill: Integer): Boolean;
- begin {CBarTherm.AdjThermometer}
- if percentToFill mod updateIncr = 0 then {only fill therm at caller specified increment}
- begin
- GetPort(savePort);
- SetPort(thermDialog);
- with thermRect do
- FillRect(top, left, bottom, (right - left) * percentToFill div 100 + left, thermPattern); {fill the thermometer}
- SetPort(savePort);
- end;
- AdjThermometer := ProcessCancelled; {return whether user pressed command-period}
- end; {CBarTherm.AdjThermometer}
-
-
- {****************************************************}
- {}
- { CPieTherm.IThermometer }
- { Initialize a CPieTherm object }
- {}
- {****************************************************}
- procedure CPieTherm.IThermometer (msg: Str255; updatePercent: Integer; fillPattern: Pattern; wantTicks: Boolean);
- var
- ticksCount, radius, i: Integer;
- dlogRect: Rect;
- p1, p2, centerOfRect: Point;
- tempPict: PicHandle;
- begin {CPieTherm.IThermometer}
- GetPort(savePort);
- inherited IThermometer(msg, updatePercent, fillPattern, wantTicks);
- SetRect(dlogRect, 10, 32, 394, 248);
- thermDialog := NewDialog(nil, dlogRect, '', False, 1, WindowPtr(-1), False, 0, nil);
- SetPort(thermDialog);
- CenterWindow(thermDialog);
- ShowWindow(thermDialog); {show the dialog}
- SetRect(dlogRect, 52, 14, 324, 65);
- TextBox(Pointer(Ord(@msg) + 1), Length(msg), dlogRect, teJustLeft);
- SetRect(thermRect, 132, 78, 254, 200);
- DrawDialog(thermDialog); {draw the dialog}
- tempPict := OpenPicture(thermDialog^.portRect); {do drawing to picture, tick marks are slow}
- FrameOval(thermRect); {frame the userItem}
-
- if wantsTicks then {caller wants tick marks displayed}
- begin
- ticksCount := Trunc(100 / updateIncr); {how many tick marks are needed}
- with thermRect do {get the center of the rect}
- SetPt(centerOfRect, (right - left) div 2 + left, (bottom - top) div 2 + top);
- radius := (thermRect.right - thermRect.left) div 2; {get the radius of the pie}
- for i := 0 to ticksCount do
- begin
- p1 := CalcPoint(updateIncr * i * 36 div 10, radius); {get x,y point on pie}
- p2 := CalcPoint(updateIncr * i * 36 div 10, radius + 5); {get x,y point on pie + extra}
- MoveTo(centerOfRect.h + p1.h, centerOfRect.v - p1.v); {make a tick mark}
- LineTo(centerOfRect.h + p2.h, centerOfRect.v - p2.v);
- end; {for i}
- end; {if wantsTicks}
- ClosePicture;
- DrawPicture(tempPict, thermDialog^.portRect);
- KillPicture(tempPict);
- InsetRect(thermRect, 1, 1); {inset rect 1 pixel so fill pattern does not erase frame}
- SetPort(savePort);
- end; {CPieTherm.IThermometer}
-
-
- {****************************************************}
- {}
- { CPieTherm.AdjThermometer }
- { Adjust a CPieTherm object }
- { Returns True if Command-period was pressed }
- {}
- {****************************************************}
- function CPieTherm.AdjThermometer (percentToFill: Integer): Boolean;
- begin {CPieTherm.AdjThermometer}
- if percentToFill mod updateIncr = 0 then {only fill therm at caller specified increment}
- begin
- GetPort(savePort);
- SetPort(thermDialog);
- with thermRect do
- FillArc(thermRect, 0, percentToFill * 36 div 10, thermPattern); {fill the thermometer}
- SetPort(savePort);
- end;
- AdjThermometer := ProcessCancelled; {return whether user pressed command-period}
- end; {CPieTherm.AdjThermometer}
-
- end. {CThermometer}